Ejemplo de apareo

Stock total de celulares


In [1]:
ls *.csv


inventarioA.csv  inventarioB.csv

In [2]:
cat inventarioA.csv


MODELO,STOCK
ifoun5SE,2
ifoun6,10
MotorolaMG5,7
MotorolaMG5Plus,5
ZamzungGalaxyA5,4

In [3]:
cat inventarioB.csv


MODELO,STOCK
ifoun5SE,3
ifoun6,5
LGSpiritLTE,4
NokiaLumia630,20
ZamzungGalaxyA5,13
ZamzungGalaxyA7,11
ZamzungGalaxyNote,9

In [4]:
import csv
import functools

IN_FILE_A = "inventarioA.csv"
IN_FILE_B = "inventarioB.csv"
OUT_FILE = "inventarioTotal.csv"

BRAND = "MODELO"
STOCK = "STOCK"

In [5]:
def get_stock_value(stockA, stockB = "0"):
    """
    Receives two stock values 'stockA' and 'stockB'. If no 'stockB' 
    is provided, it is set to '0' by default. 
    Validates that both 'stockA' and 'stockB' can be converted to
    numeric values. Raises ValueError if one of the stock values
    is not numeric or if it is an invalid amount.
    Returns the addition of both stock values.
    """
    if ((not stockA.isdigit()) or (int(stockA) < 0)):
        raise ValueError("{} is not a valid stock value!".format(stockA))
    if ((not stockB.isdigit()) or (int(stockB) < 0)):
        raise ValueError("{} is not a valid stock value!".format(stockB))
    return int(stockA) + int(stockB)

In [6]:
def count(row):
    """
    Receives a dictionary representing an inventory row.
    Returns a new dictionary with the BRAND value as
    key and the STOCK value as the associated value.
    """
    return {row[BRAND]: get_stock_value(row[STOCK])}

In [7]:
def read_next_row(reader):
    """
    Receives a csv reader and tries to read a new csv row. 
    Returns the read row. If there are no more rows to read, 
    returns None.
    """
    try:
        return next(reader)
    except StopIteration:
        return None

In [8]:
def _merge(readerA, readerB, writerOut):
    """
    Receives two csv readers 'readerA' and 'readerB'. Each reader corresponds 
    to an inventory file with the format: BRAND, STOCK. Products listed in
    both input files MUST be ordered by BRAND.
    Receives csv writer writerOut, which corresponds to the desired output
    file.
    Merges inventory files and creates one unified inventory list with the
    format: BRAND, STOCK; which is written to the provided output file.
    """
    rowA = read_next_row(readerA)
    rowB = read_next_row(readerB)
    writerOut.writeheader()

    while(rowA and rowB):
        if(rowA[BRAND] == rowB[BRAND]):
            writerOut.writerow({BRAND: rowA[BRAND], STOCK: get_stock_value(rowA[STOCK],rowB[STOCK])})
            rowA = read_next_row(readerA)
            rowB = read_next_row(readerB)
        elif (rowA[BRAND] < rowB[BRAND]):
            writerOut.writerow({BRAND: rowA[BRAND], STOCK: get_stock_value(rowA[STOCK])})
            rowA = read_next_row(readerA)
        else:
            writerOut.writerow({BRAND: rowB[BRAND], STOCK: get_stock_value(rowB[STOCK])})
            rowB = read_next_row(readerB)
    
    row = rowA if(rowA) else rowB
    reader = readerA if(rowA) else readerB
    
    while(row):
        writerOut.writerow({BRAND: row[BRAND], STOCK: get_stock_value(row[STOCK])})
        row = read_next_row(reader)

In [9]:
def merge_inventories(inputA, inputB, output, merge_function):
    """
    Receives two csv inventory files 'inputA' and 'inputB',
    with the format: BRAND, STOCK. Products listed in both 
    input files MUST be ordered by BRAND. Receives the output
    file where the unified inventory list with the format: 
    BRAND, STOCK will be saved.
    """
    with open(inputA) as csvA:
        readerA = csv.DictReader(csvA)
        with open(inputB) as csvB:
            readerB = csv.DictReader(csvB)
            with open(output, "w") as csvC:
                writerOut = csv.DictWriter(csvC, [BRAND, STOCK])
                merge_function(readerA, readerB, writerOut)

In [10]:
def main():
    merge_inventories(IN_FILE_A, IN_FILE_B, OUT_FILE, _merge)

main()

In [11]:
ls *.csv


inventarioA.csv  inventarioB.csv  inventarioTotal.csv

In [12]:
cat inventarioA.csv


MODELO,STOCK
ifoun5SE,2
ifoun6,10
MotorolaMG5,7
MotorolaMG5Plus,5
ZamzungGalaxyA5,4

In [13]:
cat inventarioB.csv


MODELO,STOCK
ifoun5SE,3
ifoun6,5
LGSpiritLTE,4
NokiaLumia630,20
ZamzungGalaxyA5,13
ZamzungGalaxyA7,11
ZamzungGalaxyNote,9

In [14]:
cat inventarioTotal.csv


MODELO,STOCK
ifoun5SE,5
ifoun6,15
LGSpiritLTE,4
MotorolaMG5,7
MotorolaMG5Plus,5
NokiaLumia630,20
ZamzungGalaxyA5,17
ZamzungGalaxyA7,11
ZamzungGalaxyNote,9